<?php
/**
 * 
 * $Id: SinaLoginClass.inc.php 518 2012-08-02 10:03:08Z 5330056@qq.com $
 */
class SinaLoginClass extends OauthBaseClass
{
	const loginAppId = '110340811';
	const loginAppKey = 'ec2b6afa1f9e01734b3354b795a2cdba';
	const accessTokenKey = 'SinaAccessTokenKeyBYiTupic.com';
	private $accessToken = '';
	private $openID = '';
	static private $scope = array('get_user_info', 'add_share,list_album', 'add_album', 'upload_pic', 'add_topic', 'add_one_blog', 'add_weibo');
	static private $callbackUrl = 'http://common.itupic.com/oAuthCallback.php';
	private $httpConnectionObj = false;
	public $cacheObj = false;
	
	public function __construct()
	{
		global $cacheObj;
		
		if(empty($cacheObj))
		{
			$this->cacheObj = $cacheObj = Bin::singtolen('CacheClass', 'Source');
		}
		else 
		{
			$this->cacheObj = $cacheObj;
		}
		
		if(!empty($_COOKIE['SinaAccessToken']) && ($accessToken = Bin::execute('BinCryptClass::decrypt', $_COOKIE['SinaAccessToken'], $this->getAccessTokenKey())))
		{
			$this->accessToken = $accessToken;
		}
		if(!empty($_COOKIE['SinaOpenID']) && ($openID = Bin::execute('BinCryptClass::decrypt', $_COOKIE['SinaOpenID'], $this->getAccessTokenKey())))
		{
			$this->openID = $openID;
		}
	}

	static public function getLoginAddress($callbackUrl = '', $scope = array(0))
	{
		$callbackUrl = urlencode(empty($callbackUrl) ? self::$callbackUrl : $callbackUrl);
		return "https://api.weibo.com/oauth2/authorize?response_type=code&client_id=".self::loginAppId."&redirect_uri={$callbackUrl}&state=".self::createRandCode();
	}
	
	public function getAccessToken($authorizationCode = '', $callbackUrl = '')
	{
		if(empty($authorizationCode))
		{
			return $this->accessToken;
		}
		$callbackUrl = urlencode(empty($callbackUrl) ? self::$callbackUrl : $callbackUrl);
				
		$url = "https://api.weibo.com/oauth2/access_token?grant_type=authorization_code&client_id=".self::loginAppId.'&client_secret='.self::loginAppKey.'&redirect_uri='.$callbackUrl.'&code='.$authorizationCode;
		
		$rsData = $this->loopGetData($url, array(), 'POST');
			
		if(empty($rsData) || ($rsData = json_decode($rsData, true)) == false)
		{
			return false;
		}
		$this->accessToken = $rsData['access_token'];
		$this->openID = $rsData['uid'];
		
		setcookie('SinaAccessToken', Bin::execute('BinCryptClass::encrypt', $this->accessToken, $this->getAccessTokenKey()), time() + $rsData['expires_in'] - 120, '/', G_CURRENT_DOMAIN);
		setcookie('SinaOpenID', Bin::execute('BinCryptClass::encrypt', $this->openID, $this->getAccessTokenKey()), time() + $rsData['expires_in'] - 120, '/', G_CURRENT_DOMAIN);
		
		return $this->accessToken;
	}
	
	public function getOpenID()
	{
		return $this->openID;
	}
	
	private function checkKey()
	{
		if(empty($this->openID) || empty($this->accessToken))
		{
			return false;
		}
		return true;
	}
	
	public function getUserInfo()
	{
		if($this->checkKey() == false)
		{
			return false;
		}
		
		$cacheKey = 'user-sina-info::'.$this->getOpenID();
		$cacheData = $this->cacheObj->getCache($cacheKey);
		if(empty($cacheData))
		{
			$url = "https://api.weibo.com/2/users/show.json?access_token={$this->accessToken}&uid={$this->openID}";
			$rsData = $this->loopGetData($url);
			if(!empty($rsData))
			{
				$rsData = converCharByArr(json_decode($rsData, true));
				$this->cacheObj->saveCache($cacheKey, $rsData, 3600 * 5);
				return $rsData;
			}
			return false;
		}
		return $cacheData;
	}
	
	private function loopGetData($url, $data = array(), $type = 'GET', $n = 3)
	{
		if(empty($this->httpConnectionObj))
		{
			$this->httpConnectionObj = Bin::singtolen('HttpConnectionClass', 'Source');
		}
		for($i = 0; $i < $n; $i ++)
		{
			$rsData = $type == 'GET' ? $this->httpConnectionObj->getData($url) : $this->httpConnectionObj->data($url, $data);
			if(!empty($rsData))
			{
				return $rsData;
			}
		}
		return $rsData;
	}
	
	public function getAppID()
	{
		return self::loginAppId;
	}
	
	static private function createRandCode()
	{
		return createRandString().'-Sina';
	}
	
	private function getAccessTokenKey()
	{
		return CommonClass::getCryptKey(self::accessTokenKey);
	}
}
